package statistics

import (
	"context"
	"git.mycaigou.com/gfyx/common/usermetadata"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/constants"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/common/utils"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/dto/aggregation"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/base/user"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/business_opportunity/contact"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/business_opportunity/oppty_status"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/clue/clue"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/clue/customer"
	"git.mycaigou.com/gfyx/micro-gfyx-oppty-service/infrastructure/repository/remote/bigdata_remote"
	aggregationPb "git.mycaigou.com/gfyx/micro-gfyx-oppty-service/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/aggregation"
	"time"
)

type statisticsService struct {
	bigDataServiceRepo    bigdata_remote.BigDataServiceRepositoryIface
	clueRepo              clue.ClueRepositoryIface
	customerRepo          customer.CustomerManageRepositoryIface
	userRepo              user.UserRepositoryIface
	mobileViewHistoryRepo contact.GfyxOpTelViewHistoryReposIface
	opptyViewRepo         oppty_status.GfyxOpptyStatusReposIface
}

// NewStatisticsService 构造函数
func NewStatisticsService(
	bigDataServiceRepo bigdata_remote.BigDataServiceRepositoryIface,
	clueRepo clue.ClueRepositoryIface,
	customerRepo customer.CustomerManageRepositoryIface,
	userRepo user.UserRepositoryIface,
	mobileViewHistoryRepo contact.GfyxOpTelViewHistoryReposIface,
	opptyViewRepo oppty_status.GfyxOpptyStatusReposIface,
) StatisticsServiceIface {
	return &statisticsService{
		bigDataServiceRepo:    bigDataServiceRepo,
		clueRepo:              clueRepo,
		customerRepo:          customerRepo,
		userRepo:              userRepo,
		mobileViewHistoryRepo: mobileViewHistoryRepo,
		opptyViewRepo:         opptyViewRepo,
	}
}

func (s *statisticsService) StatisticsData(ctx context.Context, req *aggregationPb.StatisticsDataRequest) (*aggregationPb.StatisticsDataResponse, error) {
	res := &aggregationPb.StatisticsDataResponse{}
	metaUserInfo := usermetadata.GetMetaUserInfo(ctx)
	curMonthFirstDay := time.Now().Format("2006-01") + "-01 00:00:00"
	curMonthLastDay := time.Now().Format("2006-01") + "-31 23:59:59"
	res.NewClueTotal, _ = s.clueRepo.GetCurrentMonthClueCount(ctx, metaUserInfo.UserId, curMonthFirstDay, curMonthLastDay)
	res.NewCustomerTotal, _ = s.customerRepo.GetCurrentMonthCustomerCount(ctx, metaUserInfo.UserId, curMonthFirstDay, curMonthLastDay)
	res.ContactCustomerTotal, _ = s.mobileViewHistoryRepo.GetCurrentMonthViewTimes(ctx, metaUserInfo.TenantUserUid, curMonthFirstDay, curMonthLastDay)
	res.ViewOpptyTotal, _ = s.opptyViewRepo.GetCurrentMonthViewCount(ctx, metaUserInfo.TenantUserUid, curMonthFirstDay, curMonthLastDay)
	getCustomerDynamicTotalRequest := &bigdata_remote.GetCustomerDynamicTotalRequest{
		TenantCode: metaUserInfo.TenantCode,
		StartDate:  curMonthFirstDay,
	}
	customerDynamicTotalData, err := s.bigDataServiceRepo.GetCustomerDynamicTotal(ctx, getCustomerDynamicTotalRequest)
	if err != nil {
		return res, err
	}
	if customerDynamicTotalData != nil && len(customerDynamicTotalData.List) > 0 {
		res.CustomerDynamicTotal = customerDynamicTotalData.List[0].Total
	}

	return res, nil
}

// UseRankList 应用使用排名列表
func (s *statisticsService) UseRankList(ctx context.Context, req *aggregationPb.UseRankListRequest) ([]*aggregation.UseRankItem, error) {
	var useRankList []*aggregation.UseRankItem
	var err error
	curMonthFirstDay := time.Now().Format("2006-01") + "-01 00:00:00"
	nowDate := time.Now().Format("2006-01-02 15:04:05")
	//curMonthFirstDay = "2023-01-01 00:00:00" // for test
	pageInfo := &utils.PageInfo{
		Page:     1,
		PageSize: 20,
	}
	metaUserInfo := usermetadata.GetMetaUserInfo(ctx)
	if req.Type == 3 {
		// 线索数
		useRankList, err = s.clueRepo.ClueUseRank(ctx, curMonthFirstDay, nowDate, pageInfo)
		if err != nil {
			return nil, err
		}
		if len(useRankList) == 0 {
			return nil, nil
		}
		var userIds []int64
		for _, item := range useRankList {
			userIds = append(userIds, item.UserId)
		}
		if len(userIds) != 0 {
			_, userList, _ := s.userRepo.QueryUserList(ctx, map[string]interface{}{"user_ids": userIds, "is_deleted": constants.IsDeletedFalse}, nil, "")
			userMap := make(map[int64]*user.GfyxUserPo)
			for _, item := range userList {
				userMap[item.Id] = item
			}

			for _, item := range useRankList {
				if userInfo, ok := userMap[item.UserId]; ok {
					item.UserName = userInfo.Name
				}
			}
		}

	} else if req.Type == 2 {
		// 客户数
		useRankList, err = s.customerRepo.CustomerUseRank(ctx, curMonthFirstDay, nowDate, pageInfo)
		if err != nil {
			return nil, err
		}
		if len(useRankList) == 0 {
			return nil, nil
		}
		var userIds []int64
		for _, item := range useRankList {
			userIds = append(userIds, item.UserId)
		}
		if len(userIds) != 0 {
			_, userList, _ := s.userRepo.QueryUserList(ctx, map[string]interface{}{"user_ids": userIds, "is_deleted": constants.IsDeletedFalse}, nil, "")
			userMap := make(map[int64]*user.GfyxUserPo)
			for _, item := range userList {
				userMap[item.Id] = item
			}

			for _, item := range useRankList {
				if userInfo, ok := userMap[item.UserId]; ok {
					item.UserName = userInfo.Name
				}
			}
		}

	} else if req.Type == 1 {
		// 使用次数排行
		bigDataUseRankList, err := s.bigDataServiceRepo.GetUseRankList(ctx, &bigdata_remote.GetUseRankListRequest{
			TenantCode: metaUserInfo.TenantCode,
			StartDate:  curMonthFirstDay,
			Page:       1,
			PageSize:   20,
		})
		if err != nil {
			return nil, err
		}
		if bigDataUseRankList == nil || len(bigDataUseRankList.List) == 0 {
			return nil, nil
		}
		for i, item := range bigDataUseRankList.List {
			useRankList = append(useRankList, &aggregation.UseRankItem{
				UserId:   int64(i), //此处的用户id是错误的，无业务作用，仅供前端做列表的唯一值使用
				UserName: item.UserName,
				Total:    int64(item.Total),
			})
		}
	}
	return useRankList, err
}
